/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import JsBarcode from 'jsbarcode';

const canvasDraw = {
  init(id, config) {
    const canvas = typeof id == 'object' ? id : document.getElementById(id);
    const ctx = canvas.getContext('2d');
    this.canvas = canvas;
    this.ctx = ctx;
    this.config = {
      // path: '//img.kuaidihelp.com/brand_logo/square',
      ean: 'ean',
      barcode: {
        // 条形码配置
        type: 'code128',
        config: { posX: 0, posY: 0 },
      },
      ...config,
    };
    return this;
  },
  drawStart(params) {
    const config = {
      ...this.config,
      ...params,
    };
    // 开始绘画
    const { path, brand, s_info, r_info, area, date } = config;
    let bgAttr;
    if (!brand == 'zt') {
      // 中通特殊面单
      this.canvas.height = '538';
      this.cleanCanvas();
      bgAttr = this.drawBackground(brand, path);
      this.writeText(area, {
        x: bgAttr.w / 2,
        y: bgAttr.l_2_y + 35,
        size: 24,
        align: 'center',
      }); // 区域
      this.writeText(area, {
        x: bgAttr.w / 4,
        y: bgAttr.l_3_y + 28,
        size: 16,
        align: 'center',
      }); // 区域2
      this.writeText(date, {
        x: (bgAttr.w * 3) / 4,
        y: bgAttr.l_3_y + 28,
        size: 16,
        align: 'center',
      }); // 日期
      this.writeText(`收件人： ${r_info.name}    手机/电话：${r_info.phone}`, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_4_y + 30,
        size: 16,
      }); // 收件信息
      this.writeText(`地址：${r_info.address}`, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_4_y + 30,
        rw: 43,
        size: 16,
        lh: 20,
      }); // 收件地址
      this.writeText(`发件人：${s_info.name}    手机/电话：${s_info.phone}`, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_5_y + 30,
        size: 16,
      }); // 发件信息
      this.writeText(`地址：${s_info.address}`, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_5_y + 30,
        rw: 43,
        size: 16,
        lh: 20,
      }); // 发件地址

      // this.writeText("内容物品："+service.goods_name,{"x":bgAttr.v_with+10,"y":bgAttr.l_6_y+25,"size":14});
      // this.writeText("计费重量："+service.goods_weight+(service.goods_weight.indexOf("kg")>=0?"":"kg"),{"x":bgAttr.v_with+10,"y":bgAttr.l_6_y+49,"size":14});
      // this.writeText("声明价值：￥"+service.price,{"x":bgAttr.v_with+10,"y":bgAttr.l_6_y+73,"size":14});
      // this.writeText("代付金额：￥"+service.re_pay,{"x":bgAttr.v_with+10,"y":bgAttr.l_6_y+97,"size":14});
      // this.writeText("金 额：￥"+service.to_pay,{"x":bgAttr.v_with+10,"y":bgAttr.l_6_y+121,"size":14});
    } else {
      this.canvas.height = '474';
      this.cleanCanvas();
      bgAttr = this.drawBackground(brand, path);
      this.writeText(area, {
        x: bgAttr.w / 2,
        y: bgAttr.l_2_y + 36,
        size: 24,
        align: 'center',
      }); // 区域
      this.writeText(`${r_info.name} ${r_info.phone}`, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_3_y + 30,
        size: 16,
      }); // 收件信息
      this.writeText(r_info.address, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_3_y + 30,
        rw: 37,
        size: 16,
        lh: 25,
      }); // 收件地址
      this.writeText(`${s_info.name} ${s_info.phone}`, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_4_y + 30,
        size: 16,
      }); // 发件信息
      this.writeText(s_info.address, {
        x: bgAttr.v_with + 10,
        y: bgAttr.l_4_y + 30,
        rw: 37,
        size: 16,
        lh: 25,
      }); // 发件地址
    }
    this.barCode(config.waybill_number, {
      x: (bgAttr.w - 240) / 2,
      y: bgAttr.l_1_y + (bgAttr.l_2_y - bgAttr.l_1_y - 63) / 2,
    });
  },
  cleanCanvas() {
    // 清空画板
    const { ctx } = this;
    ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
  },
  drawBackground(brand, path) {
    // 画背景板
    const { ctx } = this;
    const w = this.canvas.width;
    const h = this.canvas.height;
    const w_half = w / 2;
    let l_1_y;
    let l_2_y;
    let l_3_y;
    let l_4_y;
    let l_5_y;
    let l_6_y;
    let v_with;
    let l_x;
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, w, h);
    ctx.strokeStyle = '#030000';
    ctx.strokeRect(0, 0, w, h);
    // this.importImage("img/paper.png",{"x":0,"y":0,"w":205,"h":237});
    // 导入背景
    if (brand == 'zt') {
      // 中通特殊面单
      l_1_y = this.percentInt(h, 10);
      l_2_y = this.percentInt(h, 25);
      l_3_y = this.percentInt(h, 35);
      l_4_y = this.percentInt(h, 43);
      l_5_y = this.percentInt(h, 59);
      l_6_y = this.percentInt(h, 75);
      v_with = this.percentInt(w, 10);
      l_x = w - v_with;
      this.drawLine(0, l_4_y, w, l_4_y, 1, '#666666');
      this.drawLine(0, l_5_y, w, l_5_y, 1, '#666666');
      this.drawLine(0, l_6_y, w, l_6_y, 1, '#666666');
      this.drawLine(v_with, l_4_y, v_with, h, 1, '#666666');
      this.drawLine(w_half, l_3_y, w_half, l_4_y, 1, '#666666');
      this.drawLine(w_half, l_6_y, w_half, h, 1, '#666666');
      this.writeText('收件信息', {
        x: v_with / 2,
        y: l_4_y + (l_5_y - l_4_y) / 2 - 28,
        rw: 2.5,
        size: 14,
        align: 'center',
        lh: 14,
      });
      this.writeText('发件信息', {
        x: v_with / 2,
        y: l_5_y + (l_6_y - l_5_y) / 2 - 28,
        rw: 2.5,
        size: 14,
        align: 'center',
        lh: 14,
      });
      this.writeText('服务', {
        x: v_with / 2,
        y: l_6_y + (h - l_6_y) / 2 - 14,
        rw: 2.5,
        size: 14,
        align: 'center',
        lh: 14,
      });
      this.writeText('签收人/签收时间', { x: w_half + 10, y: l_6_y + 23, size: 13 });
      this.writeText(
        '您的签字代表您已验收此包裹，并已确认商品信息无误，包装完好，没有划痕，破损等表面质量问题。',
        { x: w_half + 10, y: l_6_y + 30, rw: 32, lh: 16, size: 12, color: '#989898' }
      );
      this.writeText('月      日', { x: w - 60, y: h - 12, size: 12 });
      const s_p = { x: w - 30, y: l_1_y };
      this.drawPolygon(
        [
          { x: s_p.x, y: s_p.y },
          { x: s_p.x + 30, y: s_p.y },
          { x: s_p.x + 30, y: s_p.y + 20 },
          { x: s_p.x, y: s_p.y + 20 },
          { x: s_p.x + 5, y: s_p.y + 10 },
        ],
        { color: '#026CB7' }
      );
      this.writeText('派', { x: s_p.x + 10, y: s_p.y + 15, color: '#fff', size: 12 });
    } else {
      l_1_y = this.percentInt(h, 13);
      l_2_y = this.percentInt(h, 32);
      l_3_y = this.percentInt(h, 44);
      l_4_y = this.percentInt(h, 64);
      l_5_y = this.percentInt(h, 84);
      v_with = this.percentInt(w, 8.5);
      l_x = w - v_with;
      this.drawLine(0, l_4_y, l_x, l_4_y, 1, '#666666');
      this.drawLine(0, l_5_y, l_x, l_5_y, 1, '#666666');
      this.drawLine(v_with, l_3_y, v_with, l_5_y, 1, '#666666');
      this.drawLine(l_x, l_3_y, l_x, h, 1, '#666666');
      this.writeText('收件', {
        x: v_with / 2,
        y: l_3_y + (l_4_y - l_3_y) / 2 - 38,
        rw: 2.5,
        size: 14,
        align: 'center',
        lh: 30,
      });
      this.writeText('发件', {
        x: v_with / 2,
        y: l_4_y + (l_4_y - l_3_y) / 2 - 38,
        rw: 2.5,
        size: 14,
        align: 'center',
        lh: 30,
      });
      this.writeText('派件联', {
        x: w - v_with / 2,
        y: l_3_y + (h - l_3_y) / 2 - 98,
        rw: 2.5,
        size: 14,
        align: 'center',
        lh: 50,
      });
      this.writeText('签收人/签收时间', { x: 10, y: l_5_y + 23, size: 13 });
      this.writeText(
        '您的签字代表您已验收此包裹，并已确认商品信息无误，包装完好，没有划痕，破损等表面质量问题。',
        { x: 10, y: l_5_y + 30, rw: 52, lh: 16, size: 12, color: '#989898' }
      );
      this.writeText('月      日', { x: w - 90, y: h - 12, size: 12 });
    }
    this.importImage(`${path}/${brand}.png`, { x: 10, y: l_1_y });
    this.drawLine(0, l_1_y, w, l_1_y, 1, '#666666');
    this.drawLine(0, l_2_y, w, l_2_y, 1, '#666666');
    this.drawLine(0, l_3_y, w, l_3_y, 1, '#666666');
    return {
      l_1_y,
      l_2_y,
      l_3_y,
      l_4_y,
      l_5_y,
      l_6_y,
      v_with,
      w,
      h,
      l_x,
    };
  },
  drawLine(fx, fy, tx, ty, w, color) {
    // 直线
    const { ctx } = this;
    ctx.strokeStyle = color;
    ctx.save();
    ctx.translate(0.5, 0.5);
    ctx.lineWidth = w;
    ctx.beginPath();
    ctx.moveTo(fx, fy);
    ctx.lineTo(tx, ty);
    ctx.stroke();
    ctx.restore();
    ctx.closePath();
  },
  drawPolygon(points, config) {
    const { w = 1, color = '#000000' } = config || {};
    // 多边形
    const pointsLen = points && points.length;
    const { ctx } = this;
    if (!points || !pointsLen) {
      return false;
    }
    ctx.strokeStyle = color;
    ctx.fillStyle = color;
    ctx.save();
    ctx.translate(0.5, 0.5);
    ctx.lineWidth = w;
    ctx.beginPath();
    ctx.moveTo(points[0].x, points[0].y);
    for (let i = 1; i < pointsLen; i++) {
      ctx.lineTo(points[i].x, points[i].y);
    }
    ctx.stroke();
    ctx.restore();
    ctx.closePath();
    ctx.fill();
  },
  barCode(number, pos) {
    // 条形码
    const { barcode: barCodeOpt } = this.config;
    const barConfig = {
      barWidth: 2,
      barHeight: 50,
      output: 'canvas',
      color: '#504F4F',
      showHRI: false,
      ...barCodeOpt.config,
      posX: pos.x,
      posY: pos.y,
    };
    const canvas2 = document.getElementById('canvasBar');
    JsBarcode(canvas2, number, {
      format: barCodeOpt.type,
      lineColor: barConfig.color,
      width: barConfig.barWidth,
      height: barConfig.barHeight,
      margin: 0,
      displayValue: false,
    });
    const src = canvas2.toDataURL('image/png', 1.0);
    this.importImage(src, {
      w: 280,
      h: 40,
      x: barConfig.posX,
      y: barConfig.posY + 110,
    });
    if (!barConfig.showHRI) {
      this.writeText(this.textPlace(number), { x: pos.x + 18, y: pos.y + 66, size: 18 });
    }
  },
  textPlace(txt) {
    const reg = /\d{1,3}/g;
    const txtArr = txt.match(reg);
    return txtArr.join('     ');
  },
  writeText(ptxt, params) {
    // 写字
    const { canvas, ctx } = this;
    const { size, align = 'left', color = '#333333', lh = 0 } = params || {};
    ctx.font = `${size || 12}px 微软雅黑`;
    ctx.textAlign = align;
    ctx.fillStyle = color;
    const lineheight = lh;

    function getTrueLength(str) {
      // 获取字符串的真实长度（字节长度）
      try {
        const len = str.length;
        let truelen = 0;
        for (let x = 0; x < len; x++) {
          if (str.charCodeAt(x) > 128) {
            truelen += 2;
          } else {
            truelen += 1;
          }
        }
        return truelen;
      } catch (err) {
        return false;
      }
    }

    function cutString(str, pleng) {
      // 按字节长度截取字符串，返回substr截取位置
      const len = str.length;
      let tlen = len;
      let nlen = 0;
      let leng = typeof pleng == 'undefined' ? canvas.width : pleng;
      leng = leng <= 2.5 ? 2.5 : leng;
      for (let x = 0; x < len; x++) {
        if (str.charCodeAt(x) > 128) {
          if (nlen + 2 < leng) {
            nlen += 2;
          } else {
            tlen = x;
            break;
          }
        } else if (nlen + 1 < leng) {
          nlen += 1;
        } else {
          tlen = x;
          break;
        }
      }
      return tlen;
    }

    let txt = ptxt;
    for (let i = 1; getTrueLength(txt) > 0; i++) {
      const tl = cutString(txt, params.rw);
      ctx.fillText(
        txt.substr(0, tl).replace(/^\s+|\s+$/, ''),
        params.x,
        i * lineheight + params.y,
        params.maxW || canvas.width
      );
      txt = txt.substr(tl);
    }
    return {
      x: params.x,
      y: params.y + lineheight,
    };
  },
  importImage(src, attr) {
    // 画图片
    const img = new Image();
    img.src = src;
    img.onload = () => {
      if (attr.w && attr.h) {
        const height = attr.h;
        this.ctx.drawImage(img, attr.x, attr.y - height - (attr.y - height) / 2, attr.w, attr.h);
      } else {
        const { height } = img;
        this.ctx.drawImage(img, attr.x, attr.y - height - (attr.y - height) / 2);
      }
    };
  },
  createImage() {
    // 生成图片
    const image = new Image();
    const src = this.canvas.toDataURL('image/png', 1.0);
    image.src = src;
    return {
      image,
      src,
    };
  },
  percentInt(num, per) {
    // 百分比取整数 有小数+1
    return Math.ceil((num * per) / 100);
  },
  downLoad() {
    const imgAttr = this.createImage();
    saveAsLocalImage(imgAttr.src);

    function saveAsLocalImage(src) {
      window.location.href = src.replace(
        'image/png',
        'image/octet-stream;Content-Disposition:attachment;filename:foobar.png'
      );
    }
  },
};

export default canvasDraw;
